home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
linux-bo
/
etherboo.000
/
etherboo
/
etherboot-2.0
/
netboot-freebsd
/
start16.S
< prev
next >
Wrap
Text File
|
1996-01-19
|
9KB
|
517 lines
/* Stack needs to be end of bss + stacksize, but not exceeding lower 640kb */
#if (RELOC+0xE000) > 0xA0000
#define STACKADDR (0xA0000-RELOC)
#else
#define STACKADDR 0xE000
#endif
/* Don't copy ROM to above 640kB */
#if (RELOC+ROMSIZE) > 0xA0000
#define RAMSIZE (0xA0000-RELOC)
#else
#define RAMSIZE ROMSIZE
#endif
;
; The startup code for BOOTROM is different from that
; in netboot-32. I don't understand why they hook
; the start vector to INT19 and in any case it
; doesn't work on my XT. So I just hook onto the
; BIOS far call. It means that ROMS residing
; above the BOOTROM haven't been called yet.
;
/**************************************************************************
START - Where all the fun begins....
**************************************************************************/
.globl _start
_start:
#ifdef BOOTROM
.word 0xaa55 /* bios extension signature */
.byte (ROMSIZE>>9) /* no. of 512B blocks */
jmp skip /* enter from bios here */
.byte 0 /* checksum */
skip:
#endif
cli
cld
mov dx,ss ;get current stack
mov ax,sp
mov bx,*(RELOC>>4) ;new ss
mov cx,*STACKADDR ;new sp
mov ss,bx
mov sp,cx
push dx ;save old stack on new stack
push ax
#ifdef BOOTROM
xor si,si ;zero for ROMs
#else
mov si,*0x100
#endif
mov ax,cs ;now relocate ourself
mov ds,ax ;ds == cs in tiny (.com) model
xor di,di ;0 is base of relocated code
mov es,bx ;new cs and ds
mov cx,*RAMSIZE
shr cx,*1
rep
movsw
jnc start1
movsb ;last byte if RAMSIZE odd
start1: mov ds,bx ;new ds
jmpf go-_start,RELOC>>4 ;switches cs and ip
go: call _main ;now executing in RAM
.globl _exit
_exit:
; we reset sp to the location just before entering main
; instead of relying on the return from main because exit
; could have been called from anywhere
mov cx,*(STACKADDR-4)
mov sp,cx
pop ax ;restore old stack
pop bx
mov ss,bx
mov sp,ax
#ifdef BOOTROM
retf
#else
int *0x19
#endif
/**************************************************************************
CURRTICKS - Get Time
**************************************************************************/
.globl _currticks
_currticks:
push cx
xor dx,dx
xor ax,ax
int *0x1a
mov ax,dx
mov dx,cx
pop cx
ret
/**************************************************************************
PUTCHAR - Print a character
**************************************************************************/
.globl _putchar
_putchar:
push bp
mov bp,sp
push cx
push bx
movb cl,4[bp]
mov bx,*1
movb ah,*0x0e
movb al,cl
int *0x10
pop bx
pop cx
pop bp
ret
/**************************************************************************
GETCHAR - Get a character
**************************************************************************/
.globl _getchar
_getchar:
push bx
movb ah,*0x0
int *0x16
movb bl,al
xor ax,ax
movb al,bl
pop bx
ret
/**************************************************************************
ISKEY - Check for keyboard interrupt
**************************************************************************/
.globl _iskey
_iskey:
push bx
xor bx,bx
movb ah,*0x1
int *0x16
jz iskey1
movb bl,al
iskey1:
xor ax,ax
movb al,bl
pop bx
ret
/**************************************************************************
MEMSIZE - Determine size of extended memory
**************************************************************************/
.globl _memsize
_memsize:
push bx
mov ax,*0x8800
int *0x15
mov bx,ax
xor ax,ax
mov ax,bx
pop bx
ret
/**************************************************************************
START_PROG - Call program code
**************************************************************************/
.globl _start_linux
_start_linux:
call sl1
ret
sl1: jmpf *0x0,*0x9020
.globl _xstart
;
; usage: xstart(execaddr, headeraddr, bootpaddr);
; 4,6 8,10 12,14
;
_xstart:
push bp
mov bp,sp
push bx
push cx
mov ax,14[bp]
push ax /* bootp record */
mov ax,12[bp]
push ax
mov ax,10[bp]
push ax /* file header */
mov ax,8[bp]
push ax
mov ax,cs
push ax /* return address */
mov ax,*xs1-_start
push ax
mov ax,6[bp]
push ax /* exec addr */
mov ax,4[bp]
push ax
retf /* jump intersegment using a return */
xs1: pop bp
pop cx
pop bx
ret
; int inw(int port);
; reads a word from the i/o port port and returns it
.globl _inw
_inw:
pop bx
pop dx
dec sp
dec sp
inw
jmp bx
; int inb(int port);
; reads a byte from the i/o port port and returns it
.globl _inb
_inb:
pop bx
pop dx
dec sp
dec sp
inb
sub ah,ah
jmp bx
; int insw(int port, char *dst, int nwords);
; block read from i/o port
.globl _insw
_insw:
pop bx ;return address
pop dx ;port
pop di ;destination
pop cx ;count
inswloop:
jcxz inswret
inw
mov [di],ax
inc di
inc di
dec cx
jmp inswloop
inswret:
sub sp,*6 ;precompensate for add in caller
jmp bx
; void outw(int port, int value);
; writes the word value to the i/o port port
.globl _outw
_outw:
pop bx
pop dx
pop ax
sub sp,*4
outw
jmp bx
; void outb(int port, char value);
; writes the byte value to the i/o port port
.globl _outb
_outb:
pop bx
pop dx
pop ax
sub sp,*4
outb
jmp bx
; int outsw(int port, char *src, int nwords);
; block write from i/o port
.globl _outsw
_outsw:
pop bx ;return address
pop dx ;port
pop di ;destination
pop cx ;count
outswloop:
jcxz outswret
mov ax,[di]
outw
inc di
inc di
dec cx
jmp outswloop
outswret:
sub sp,*6 ;precompensate for add in caller
jmp bx
;*************************************************************************
; longswap
; swap the bytes of a long integer from pc
; order (reverse) to in-order. this will work both ways.
; returns the new long value
; usage:
; l2 = htonl/ntohl(l)
;
.globl _htonl,_ntohl
_htonl:
_ntohl:
push bp
mov bp,sp
mov ax,6[bp] ;high bytes of the long int
mov dx,4[bp] ;low bytes of the long int
;
; get the data
;
xchgb al,ah ;swap them, these are now low
xchgb dl,dh ;swap the others
pop bp
ret
;
;*************************************************************************
; intswap
; swap the bytes of an integer, returns the swapped integer
;
; usage: i = htons/ntohs(i);
;
.globl _htons,_ntohs
_htons:
_ntohs:
push bp
mov bp,sp
mov ax,4[bp]
xchgb al,ah
pop bp
ret
; lintoseg
; extracts the segment from a linear address in bx,ax
; returns segment in ax
;
lintoseg:
and ax,*0xfff0 ;clear bottom 4 bits
clc
rcr bx,*1 ;and shift segment 4 bits down
rcr ax,*1
rcr bx,*1
rcr ax,*1
rcr bx,*1
rcr ax,*1
rcr bx,*1
rcr ax,*1
ret
;
;*************************************************************************
; bcopyf
; like bcopy, but copies intersegment
;
; usage: bcopyf(p, fp, n);
;
.globl _bcopyf
_bcopyf:
push bp
mov bp,sp
push di
push si
push es
cld
; 4[bp] = p, 6,8[bp] = fp, A[bp] = n
mov si,4[bp] ;p
mov ax,6[bp] ;fp low word
mov di,ax
and di,*0xf ;keep LS 4 bits
mov bx,8[bp]
call lintoseg
mov es,ax
mov cx,$A[bp]
shr cx,*1
rep
movsw
jnc bcopyf1
movsb
bcopyf1:
pop es
pop si
pop di
pop bp
ret
;
;*************************************************************************
; fbcopy
; like bcopy, but copies intersegment
;
; usage: fbcopy(fp, p, n);
;
.globl _fbcopy
_fbcopy:
push bp
mov bp,sp
push di
push si
push es
cld
mov ax,ds
mov es,ax
; 4,6[bp] = fp, 8[bp] = p, A[bp] = n
mov ax,4[bp] ;fp low word
mov si,ax
and si,*0xf ;keep LS 4 bits
mov bx,6[bp]
call lintoseg
mov ds,ax
mov di,8[bp] ;p
mov cx,$A[bp]
shr cx,*1
rep
movsw
jnc fcopyb1
movsb
fcopyb1:
mov ax,es
mov ds,ax
pop es
pop si
pop di
pop bp
ret
;
;*************************************************************************
; fpeekw
; returns one word from a far address
;
; usage: fpeekw(fp);
;
.globl _fpeekw
_fpeekw:
push bp
mov bp,sp
push si
; 4,6[bp] = fp, 8[bp] = p, A[bp] = n
mov ax,4[bp] ;fp low word
mov si,ax
and si,*0xf ;keep LS 4 bits
mov bx,6[bp]
call lintoseg
mov bx,ax
mov ax,[bx+si]
pop di
pop bp
ret
;
;*************************************************************************
; bzerof
; like bzero, but zeros any segment
;
; usage: bzerof(fp, n);
;
.globl _bzerof
_bzerof:
push bp
mov bp,sp
push di
push si
push es
cld
; 4,6[bp] = fp, 8[bp] = n
mov ax,4[bp] ;fp low word
mov di,ax
and di,*0xf ;keep LS 4 bits
mov bx,6[bp]
call lintoseg
mov es,ax
mov cx,$8[bp]
xor ax,ax
shr cx,*1
rep
stosw
jnc bzerof1
stosb
bzerof1:
pop es
pop si
pop di
pop bp
ret
;
;*************************************************************************
; fbsame
; returns 1 if all bytes from fp[0] to fp[n-1] have the value c
;
; usage: fbsame(fp, c, n);
;
.globl _fbsame
_fbsame:
push bp
mov bp,sp
push di
push si
cld
; 4,6[bp] = fp, 8[bp] = c, A[bp] = n
mov ax,4[bp] ;fp low word
mov di,ax
and di,*0xf ;keep LS 4 bits
mov bx,6[bp]
call lintoseg
mov es,ax
mov ax,8[bp] ;c
mov cx,$A[bp]
repe
scasb
mov ax,*0 ;not xor because want to preserve z
jne fbsameret
inc ax
fbsameret:
pop si
pop di
pop bp
ret